package cn.b.sky.form.service.impl;

import cn.b.sky.common.model.BatchJobReport;
import cn.b.sky.common.model.Page;
import cn.b.sky.common.utils.DatabaseUtils;
import cn.b.sky.i18n.utils.LocaleResourceBundle;
import cn.b.sky.form.dao.BusinessFieldDao;
import cn.b.sky.form.dao.BusinessFieldValueDao;
import cn.b.sky.form.dao.BusinessTypeDao;
import cn.b.sky.form.enums.TableTypeEnum;
import cn.b.sky.form.model.BusinessDataTypeDef;
import cn.b.sky.form.model.BusinessField;
import cn.b.sky.form.model.BusinessFieldTypeDef;
import cn.b.sky.form.model.BusinessType;
import cn.b.sky.form.model.condition.BusinessFieldCondition;
import cn.b.sky.form.model.condition.BusinessFieldValueCondition;
import cn.b.sky.form.model.condition.BusinessTypeCondition;
import cn.b.sky.form.service.BusinessTableService;
import cn.b.sky.form.service.BusinessTypeService;
import cn.b.sky.form.utils.BusinessTypeDefinitionUtils;
import cn.b.sky.user.SecurityContextUtil;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * 
 * <strong>Title : BusinessTypeServiceImpl.java<br></strong>
 * <strong>Package : cn.b.sky.flowable.service.impl<br></strong>
 * <strong>Description : </strong>业务类型操作业务类实现<br> 
 * <strong>Create on : 2016-09-27 下午05:56:14<br></strong>
 * <p>
 * @author JunLin.Yang<br>
 * @version <strong>v1.0.0</strong>
 */
@Service("businessTypeService")
public class BusinessTypeServiceImpl implements BusinessTypeService {

  private static final Logger LOGGER = LoggerFactory.getLogger(BusinessTypeServiceImpl.class);

  @Resource
  private BusinessTypeDao businessTypeDao;

  @Resource
  private BusinessFieldDao businessFieldDao;

  @Resource
  private BusinessFieldValueDao businessFieldValueDao;

  @Resource
  private BusinessTableService businessTableService;

  @Override
  public int insertBusinessType(BusinessType data) {
    if (null == data) {
      return 0;
    }
    data.preProcessingToStore();
    return this.businessTypeDao.insertBusinessType(data);
  }

  @Override
  public int updateBusinessType(BusinessType data) {
    if (null == data) {
      return 0;
    }
    data.preProcessingToStore();
    return this.businessTypeDao.updateBusinessType(data);
  }

  @Override
  public BatchJobReport deleteBusinessType(BusinessType data) {
    if (null == data) {
      return new BatchJobReport("", "data is null", false);
    }
    data.preProcessingToStore();
    return this.deleteBusinessTypeByPrimaryKey(data.getSiteCode(), data.getBusinessType());
  }

  @Override
  public long getBusinessTypesCount() {
    return this.businessTypeDao.getBusinessTypesCount();
  }

  @Override
  public List<BusinessType> selectBusinessTypes() {
    return this.businessTypeDao.selectBusinessTypes();
  }

  @Override
  public BatchJobReport deleteBusinessTypeByPrimaryKey(String siteCode, String businessType) {
    String cause = "";
    Boolean success = true;
    try {
      BusinessFieldValueCondition businessFieldValueCondition = new BusinessFieldValueCondition();
      businessFieldValueCondition.setSiteCode(siteCode);
      businessFieldValueCondition.setBusinessType(businessType);
      this.businessFieldValueDao.deleteBusinessFieldValueByCondition(businessFieldValueCondition);

      BusinessFieldCondition businessFieldCondition = new BusinessFieldCondition();
      businessFieldCondition.setSiteCode(siteCode);
      businessFieldCondition.setBusinessType(businessType);
      this.businessFieldDao.deleteBusinessFieldByCondition(businessFieldCondition);
      this.businessTypeDao.deleteBusinessTypeByPrimaryKey(siteCode, businessType);
      success = true;
    } catch (Exception e) {
      LOGGER.error("{}", e);
      TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
      if (DatabaseUtils.isConstraintsError(e.getMessage())) {
        // 外键删除已存在提示
        cause = LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
            SecurityContextUtil.getLanguageCode(), "dataBaseOperationPkFail.M")
            + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                SecurityContextUtil.getLanguageCode(), "notDelete.M");
      } else {
        cause = e.getMessage();
      }
      success = false;
    }
    return new BatchJobReport(businessType, cause, success);
  }

  @Override
  public BusinessType getBusinessTypeByPrimaryKey(String siteCode, String businessType) {
    return this.businessTypeDao.getBusinessTypeByPrimaryKey(siteCode, businessType);
  }

  @Override
  public boolean existBusinessTypeByPrimaryKey(String siteCode, String businessType) {
    return this.businessTypeDao.existBusinessTypeByPrimaryKey(siteCode, businessType);
  }

  @Override
  public boolean existsBusinessTypeByCondition(BusinessTypeCondition condition) {
    return this.businessTypeDao.existsBusinessTypeByCondition(condition);
  }

  @Override
  public BusinessType getBusinessTypeByCondition(BusinessTypeCondition condition) {
    return this.businessTypeDao.getBusinessTypeByCondition(condition);
  }

  @Override
  public List<BusinessType> selectBusinessTypesByCondition(BusinessTypeCondition condition) {
    return this.businessTypeDao.selectBusinessTypesByCondition(condition);
  }

  @Override
  public List<BusinessType> selectBusinessTypePageDataByCondition(BusinessTypeCondition condition) {
    return this.businessTypeDao.selectBusinessTypePageDataByCondition(condition);
  }

  @Override
  public Page selectBusinessTypePageByCondition(BusinessTypeCondition condition) {
    condition.setData(this.businessTypeDao.selectBusinessTypePageDataByCondition(condition));
    condition.setTotalCount(this.businessTypeDao.getBusinessTypesCountByCondition(condition));
    return condition;
  }

  @Override
  public long getBusinessTypesCountByCondition(BusinessTypeCondition condition) {
    return this.businessTypeDao.getBusinessTypesCountByCondition(condition);
  }

  @Override
  public BusinessType getBusinessTypeAndFields(String siteCode, String businessType) {
    BusinessType businessTypeData = this.businessTypeDao.getBusinessTypeByPrimaryKey(siteCode, businessType);
    if (null != businessTypeData) {
      BusinessFieldCondition businessFieldCondition = new BusinessFieldCondition();
      businessFieldCondition.setSiteCode(siteCode);
      businessFieldCondition.setBusinessType(businessType);
      businessFieldCondition.setOrderField("systemFieldFlag");
      businessFieldCondition.setOrderDirection("asc");
      businessTypeData
          .setBusinessFieldList(this.businessFieldDao.selectBusinessFieldsByCondition(businessFieldCondition));
      
      //若存在字段信息，则进行类型文本信息的补全
      if (null != businessTypeData && !CollectionUtils.isEmpty(businessTypeData.getBusinessFieldList())) {
        BusinessDataTypeDef dataTypeDef = null;
        BusinessFieldTypeDef fieldTypeDef = null;
        for (BusinessField businessField : businessTypeData.getBusinessFieldList()) {
          dataTypeDef = BusinessTypeDefinitionUtils.getDataType(businessField.getDataType());
          fieldTypeDef = BusinessTypeDefinitionUtils.getFieldType(businessField.getFieldType());
          if (null != dataTypeDef) {
            businessField.setDataTypeText(dataTypeDef.getText());
          }

          if (null != fieldTypeDef) {
            businessField.setFieldTypeText(fieldTypeDef.getText());
          }
        }
      }
    }
    return businessTypeData;
  }

  @Override
  public int insertBusinessTypeAndInitFields(BusinessType data) {
    if (null == data) {
      return 0;
    }
    data.preProcessingToStore();
    int n = this.businessTypeDao.insertBusinessType(data);
    //不用file操作，jar没法获取相关的路径文件
    InputStream  in = BusinessTypeServiceImpl.class.getResourceAsStream("/workflow_business_initfields.json");
    if (in != null) {
      //如果初始化字段文件存在，则进行保存
      try {
        String initFieldJson = IOUtils.toString(in, "UTF-8");
        if (StringUtils.isNotBlank(initFieldJson)) {
          //如果存在初始化字段数据信息，则初始化
          List<BusinessField> fieldList = JSONObject.parseArray(initFieldJson, BusinessField.class);

          if (!CollectionUtils.isEmpty(fieldList)) {
            for (BusinessField businessField : fieldList) {
              businessField.setSiteCode(data.getSiteCode());
              businessField.setBusinessType(data.getBusinessType());
              this.businessFieldDao.insertBusinessField(businessField);
            }

          }
        }
      } catch (IOException e) {
        LOGGER.error("{}", e);
      }

    }
    return n;
  }

  @Override
  public boolean doCreateOrUpdateBusinessTable(String siteCode, String businessType) {

    if (StringUtils.isNotBlank(businessType)) {
      BusinessType businessTypeData = this.businessTypeDao.getBusinessTypeByPrimaryKey(siteCode, businessType);
      if (null != businessTypeData 
          && this.businessTableService.doCreateOrUpdateBusinessTable(
              TableTypeEnum.MYSQL, siteCode, businessType)) {
        businessTypeData.setTableCreateFlag(1);
        return 0 < this.businessTypeDao.updateBusinessType(businessTypeData);
      }
    }

    return false;
  }
}
